<?php

	require_once('../includes/googleApi.php');
	require_once('../includes/provider-account.php');
	require_once('../includes/provider-account-lobby.php');
	require_once('../includes/provider-lobby.php');
	require_once('../includes/provider-lobby-voice.php');

	$lp = new LobbyProvider();
	$ap = new AccountProvider();
	$alp = new AccountLobbyProvider();

	function getUser($result, $err) {
		GLOBAL $ap;
		$r = $ap->get($_SESSION['uid']);
		if (empty($r)) {
			/* unexpected case */
			$result = FALSE;
			$err = 'unexpected case unmatched google UID.';
			return FALSE;
		} else {
			return $r[$_SESSION['uid']];
		}
	}

	function getLobby($lobby_id, $result, $err)  {
		GLOBAL $lp;
		$lobbies = $lp->get($lobby_id);
		if (empty($lobbies) || ! isset($lobbies[$lobby_id])) {
			$result = FALSE;
			$err = 'unknown lobby id: ' . $lobby_id;
			return FALSE;
		} else {
			return $lobbies[$lobby_id];
		}
	}

	function getCurrentLobbyId($result, $err) {
		GLOBAL $alp;
		$r = $alp->get($_SESSION['uid']);
		if (empty($r)) {
			$err = 'no associated lobby with this account.';
			$result = FALSE;
			break;
		}
		
		return $r[$_SESSION['uid']]['lid'];
	}

	function boardcast($action, $value, $result, $err) {
		$lid = getCurrentLobbyId(&$result, &$err);
		$lobby = getLobby($lid, &$result, &$err);

		$lvp = new LobbyVoiceProvider();

		return $lvp->write(NULL, array(
			'lid' => $lid,
			'uid' => 0,			/* boardcast using 0 as uid */
			'alias' => $action,	/* boardcast using action as alias */
			'txt' => $value
		));
	}

	function speak($txt, $result, $err, $lobby = NULL) {

		if ($lobby_name == NULL) {
			$lid = getCurrentLobbyId(&$result, &$err);
			$lobby = getLobby($lid, &$result, &$err);
		}

		$lvp = new LobbyVoiceProvider();

		return $lvp->write(NULL, array(
			'lid' => $lid,
			'uid' => $_SESSION['uid'],
			'alias' => $lobby['lobby_id'][$_SESSION['uid']]['alias'],
			'txt' => $txt
		));
	}

	function replaceScore($matches) {

		$dir = 1;
		if (sizeof($matches) == 3) {
			// --
			// ++
			$name = $matches[1];
			$val = 1;
			if ($matches[2] == '--') {
				$val *= -1;
				$dir = -1;
			}
		} else if (sizeof($matches) == 5) {
			// -=
			// +=
			$name = $matches[1];
			$val = $matches[4];
			if ($matches[3] == '-=') {
				$val *= -1;
				$dir = -1;
			}
		}

		$lid = getCurrentLobbyId(&$result, &$err);
		$lobby = getLobby($lid, &$result, &$err);
		$score = floatval($lobby['lobby_score'][$name]['score']);
		$score += $val;

		GLOBAL $lp;
		$lp->write($lid, array(
			'lobby_score' => array(
				$name => array(
					'score' => $score
				)
			)
		));

		// $txt = 'score = ' . $val . ' / ' . $score . ' / ' . $dir . ' / ' . $name;
		$txt = ($dir > 0 ? 'woot!' : 'ouch!') . ' now at ' . $score;

		speak($matches[0] . ' [' . $txt . ']', &$result, &$err, $lobby);
	}

	// --------------------------------------------------------------------

	$_callback = $_REQUEST['callback'];
	$_action = $_REQUEST['act'];

	// init
	$result = TRUE;

	if ( ! isset($_SESSION['uid'])) {
		$result = FALSE;
		$err = 'login first.';
	}
	elseif (isset($_action))
	{
		switch ($_action) 
		{
			case 'help':
				$data['to_screen'][] = 'Help message.';
				$data['to_screen'][] = '-------------';
				$data['to_screen'][] = '/alias {new name}';
				$data['to_screen'][] = '/rename {new name}';
				$data['to_screen'][] = '/heading {new room heading text}';
				break;
			case 'alias':
			case 'rename':
				$new_name = trim(stripslashes($_REQUEST['data']));
				if (sizeof(explode(' ', $new_name)) > 1) {
					$result =FALSE;
					$err = 'space is not allowed: ' . $new_name;
					break;
				}

				if (sizeof($new_name)>=50) {
					$result =FALSE;
					$err = 'too long sas: ' . $new_name;
					break;
				}

				$lid = getCurrentLobbyId(&$result, &$err);
				$lobby = getLobby($lid, &$result, &$err);
				$old_name = $lobby['lobby_id'][$_SESSION['uid']]['alias'];

				if ($old_name == $new_name) {
					$result =FALSE;
					$err = 'you are already ' . $old_name;
					break;
				}

				$r = $lp->get(NULL, array(
						'sub_cond' => array(
							'lobby_id' => array(
								'alias' => $new_name,
								'uid!not' => $_SESSION['uid']
							)
						)
					));
				if ( ! empty($r)) {
					$result =FALSE;
					$err = 'name already taken.';
					break;
				}
				
				$lp->write($lid, array(
					'lobby_id' => array(
						$_SESSION['uid'] => array(
							'lid' => $lid,
							'alias' => $new_name
						)
					)
				));
				boardcast('print', $old_name . ' is now known as ' . $new_name, &$result, &$err);
				break;
			case 'heading':
				$lid = getCurrentLobbyId(&$result, &$err);
				$lobby = getLobby($lid, &$result, &$err);
				$changer_name = $lobby['lobby_id'][$_SESSION['uid']]['alias'];
				$new_name = stripslashes($_REQUEST['data']) . ' by ' . $changer_name;

				$lp->write($lid, array(
						'heading' => $new_name
					));

				boardcast('s_head', $new_name, &$result, &$err);
				break;
			case '$init':
				$r = $alp->get($_SESSION['uid']);
				if (empty($r)) {
					$data['lobby_id'] = NULL;
					break;
				}
				
				$lobby_id = $r[$_SESSION['uid']]['lid'];
				$data['lobby_id'] = $lobby_id;
				$data['uid'] = $_SESSION['uid'];
				$data['to_screen'][] = 'initialization completed.';
				// auto join (no break;)
			case 'join':
				/* find associated $lobby_id */
				if ( ! isset($lobby_id)) {
					$lobby_name = stripslashes($_REQUEST['data']);

					$r = $lp->get(NULL, array('name' => $lobby_name));
					if (empty($r)) {
						$result = FALSE;
						$err = 'unknown lobby: ' . $lobby_name;
						break;
					} else {
						$lobby_id = array_keys($r);
						$lobby_id = $lobby_id[0];
						$data['lobby_id'] = $lobby_id;
					}
				}

				$lobby = getLobby($lobby_id, &$result, &$err);
				if ( ! $lobby) {
					/* result and err is already set */
					break;
				}

				// find if already exist in the lobby
				if ( ! isset($lobby['lobby_id'][$_SESSION['uid']])) {
					$user = getUser(&$result, &$err);
					if ( ! $user) {
						/* result and err is already set */
						break;
					}

					$screen_name = $user['screen_name'];
					
					$i = 0;
					do {
						if ($i)
							$test_name = $screen_name . '-' . $i;
						else {
							$test_name = $screen_name;
						}
						$r = $lp->get(NULL, array(
							'sub_cond' => array(
								'lobby_id' => array(
									'alias' => $test_name
								)
							)
						));
						$i ++;
					} while ( ! empty($r));
					$screen_name = $test_name;

					$lp->write($lobby_id, array(
						'lobby_id' => array(
							$_SESSION['uid'] => array (
								'lid' => $lobby_id,
								'alias' => $screen_name = $user['screen_name']
							)
						)
					));

					// reload it
					$lobby = getLobby($lobby_id, &$result, &$err);
					if ( ! $lobby) {
						/* result and err is already set */
						break;
					}
				}
				$data['alias'] = $lobby['lobby_id'][$_SESSION['uid']]['alias'];

				// return data chunk
				$data['heading'] = $lobby['heading'];
				$data['name'] = $lobby['name'];

				// joined success
				$alp->write($_SESSION['uid'], array(
					'lid' => $lobby_id
				));
				$data['to_screen'][] = 'joined ' . $data['name'];
				// skip break; (do first poll)
			case '$poll':
				$lvp = new LobbyVoiceProvider();

				if ( ! isset($lobby)) {
					if ( ! isset($lobby_id)) {
						$lobby_id = getCurrentLobbyId(&$result, &$err);
					}
					$lobby = getLobby($lobby_id, &$result, &$err);
					if ( ! $lobby) {
						/* result and err is already set */
						break;
					}
				}

				$data['poll'] = $lvp->get(NULL, array(
					'vid >' => $lobby['lobby_id'][$_SESSION['uid']]['vid_stamp']
				), array(
					'sort' => 'vid'
				));

				if ( ! empty($data['poll'])) {
					$vid_stamp = max(array_keys($data['poll']));
					/* update vid_stamp */
					$lp->write($lobby_id, array(
						'lobby_id' => array(
							$_SESSION['uid'] => array (
								'vid_stamp' => $vid_stamp
							)
						)
					));
				}
				break;
			case 'create':	/* create lobby */
				$user = getUser(&$result, &$err);
				if ( ! $user) {
					/* result and err is already set */
					break;
				}
				$_lobby_name = stripslashes($_REQUEST['data']);
				$data['lobby_id'] = $lp->write(NULL, array(
						'name' => $_lobby_name,
						'heading' => 'welcome to ' . $_lobby_name,
						'lobby_id' => array(
							$_SESSION['uid'] => array (
								'alias' => $screen_name
							)
						)
					));
				break;
			case 'speak':
				/* check if account is binded with any lobby? */
				$txt = stripslashes($_REQUEST['data']);

				$parts = explode(' ', $txt);
				if (preg_match('/(.+)(\+\+|--|(\+=|-=)\d+)/', $parts[0])) {
					preg_replace_callback(
						'/(.+)(\+\+|--|(\+=|-=)(\d+))/', 
						'replaceScore', 
						$parts[0]);
				} else {
					$data['spoken_voice_id'] = speak($txt, &$result, &$err);
				}
				break;
			default:
				$err = 'unknown \'act\' value: '.$_action;
				$result = FALSE;
				break;
		}
	}
	else
	{
		$err = 'unset \'act\' value';
		$result = FALSE;
	}

	// enclosure
	echo $_callback.'('.json_encode(array(
			'result' => $result,
			'data' => $data,
			'err' => $err
		)).');';
?>